package com.haha.keymap.v3;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.haha.keymap.v1.CustomColor;
import com.haha.keymap.v1.CustomPoint;
import com.haha.keymap.v1.SkillConfigData;
import com.haha.keymap.v1.SkillInfo;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyAdapter;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @author shenlinnan
 * @date 2025/7/20 16:07
 */
public class KeyMapperFX extends Application implements NativeKeyListener {

    private SkillConfigData skillConfigData;
    private Robot robot;
    private boolean startStatus = false;
    private int step = 0;
    private Label statusLabel;
    private Stage primaryStage;

    /**
     * 存储第一步坐标
     */
    private Point point1;
    /**
     * 存储第二步坐标
     */
    private Point point2;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        this.primaryStage = primaryStage;
        try {
            skillConfigData = getConfigInfo();
            robot = new Robot();
            initUI(primaryStage);
        } catch (AWTException e) {
            e.printStackTrace();
            showMessageDialog("初始化错误", "无法创建Robot实例: " + e.getMessage());
        }
    }

    private SkillConfigData getConfigInfo() {
        // 获取当前工作目录
        String currentDir = System.getProperty("user.dir");
        String filePath = Paths.get(currentDir, "config.json").toString();
        File file = new File(filePath);
        if (!file.exists()) {
            return null;
        }

        Gson gson = new GsonBuilder().setPrettyPrinting().create();

        try (FileReader reader = new FileReader(filePath)) {
            java.lang.reflect.Type configType = new TypeToken<SkillConfigData>() {
            }.getType();
            return gson.fromJson(reader, configType);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void initUI(Stage primaryStage) {
        primaryStage.setTitle("键映射器");
        primaryStage.setWidth(400);
        primaryStage.setHeight(300);

        // 创建根布局 - 使用BorderPane替代VBox
        BorderPane root = new BorderPane();

        // 创建顶部按钮面板
        HBox buttonBox = new HBox(20);
        buttonBox.setPadding(new Insets(15));
        buttonBox.setAlignment(Pos.CENTER);

        // 创建按钮
        Button startButton = new Button("启动");
        startButton.setPrefSize(100, 40);
        Button configButton = new Button("配置");
        configButton.setPrefSize(100, 40);

        buttonBox.getChildren().addAll(startButton, configButton);

        // 创建状态标签 - 放在左侧底部
        statusLabel = new Label("已停止");
        statusLabel.setTextFill(javafx.scene.paint.Color.RED);
        statusLabel.setPadding(new Insets(0, 0, 10, 20));

        // 创建版本号标签 - 放在右侧底部
        Label versionLabel = new Label("v1.0.0");
        versionLabel.setTextFill(javafx.scene.paint.Color.GRAY);
        versionLabel.setPadding(new Insets(0, 20, 10, 0)); // 右边距20，下边距10

        // 创建底部面板 - 使用HBox分开左右区域
        HBox bottomBox = new HBox();
        bottomBox.setAlignment(Pos.CENTER_LEFT);

        // 左侧区域 - 状态标签
        HBox leftBottom = new HBox();
        leftBottom.setAlignment(Pos.CENTER_LEFT);
        leftBottom.getChildren().add(statusLabel);

        // 右侧区域 - 版本号标签
        HBox rightBottom = new HBox();
        rightBottom.setAlignment(Pos.CENTER_RIGHT);
        rightBottom.getChildren().add(versionLabel);

        // 使用Region作为弹簧填充中间区域
        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);

        // 添加到底部面板
        bottomBox.getChildren().addAll(leftBottom, spacer, rightBottom);

        // 添加到根布局
        root.setTop(buttonBox);
        root.setBottom(bottomBox);

        // 创建场景
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();

        // 注册全局键盘监听
        try {
            GlobalScreen.registerNativeHook();
            GlobalScreen.addNativeKeyListener(this);

            // 禁用JNativeHook日志
            java.util.logging.Logger.getLogger(GlobalScreen.class.getPackage().getName()).setLevel(java.util.logging.Level.OFF);
        } catch (NativeHookException ex) {
            ex.printStackTrace();
            showMessageDialog("初始化错误", "无法注册全局键盘监听: " + ex.getMessage());
        }

        // 按钮事件处理
        startButton.setOnAction(e -> {
            if ("启动".equals(startButton.getText())) {
                // 检查配置数据是否为空
                if (skillConfigData == null) {
                    showMessageDialog("配置错误", "请先进行配置！");
                    return;
                }

                startButton.setText("关闭");
                statusLabel.setText("已启动");
                statusLabel.setTextFill(javafx.scene.paint.Color.GREEN);
                startStatus = true;
            } else {
                startButton.setText("启动");
                statusLabel.setText("已停止");
                statusLabel.setTextFill(javafx.scene.paint.Color.RED);
                startStatus = false;
            }
        });

        configButton.setOnAction(e -> showConfigDialog());

        // 窗口关闭事件
        primaryStage.setOnCloseRequest(event -> {
            try {
                GlobalScreen.unregisterNativeHook();
            } catch (NativeHookException ex) {
                ex.printStackTrace();
            }
        });
    }

    private void showConfigDialog() {
        Stage configStage = new Stage();
        configStage.initModality(Modality.APPLICATION_MODAL);
        configStage.initOwner(primaryStage);
        configStage.setTitle("配置向导");
        configStage.setWidth(600);
        configStage.setHeight(400);
        configStage.setResizable(false);

        // 创建主布局
        VBox mainLayout = new VBox(15);
        mainLayout.setPadding(new Insets(20));
        mainLayout.setAlignment(Pos.TOP_LEFT);

        // 创建步骤1组件
        Label step1Label = new Label("第一步：切换到游戏界面，将鼠标移动到技能提示图标上靠近中心随意的点上，按下F11");
        step1Label.setWrapText(true);
        Label coord1Label = new Label("坐标：尚未记录");

        // 创建步骤2组件（初始隐藏）
        Label step2Label = new Label("第二步：切换到游戏界面，将鼠标移动到技能提示图标上另一个点上，按下F11");
        step2Label.setWrapText(true);
        step2Label.setVisible(false);
        Label coord2Label = new Label("坐标：尚未记录");
        coord2Label.setVisible(false);

        // 创建保存按钮
        Button saveButton = new Button("保存配置");
        saveButton.setOnAction(e -> {
            // 保存配置到JSON文件
            saveConfigToFile();

            // 更新主界面的配置数据
            skillConfigData = getConfigInfo();
            showMessageDialog("配置保存", "配置已保存");
            configStage.close();
            step = 0;
        });

        // 添加到布局
        mainLayout.getChildren().addAll(
                step1Label, coord1Label,
                step2Label, coord2Label,
                saveButton
        );

        // 创建场景
        Scene configScene = new Scene(mainLayout);
        configStage.setScene(configScene);

        // 键盘监听器
        NativeKeyListener configListener = new NativeKeyAdapter() {
            @Override
            public void nativeKeyPressed(NativeKeyEvent e) {
                if (e.getKeyCode() == NativeKeyEvent.VC_F11) {
                    Point mousePos = MouseInfo.getPointerInfo().getLocation();

                    // 在JavaFX线程中更新UI
                    Platform.runLater(() -> {
                        if (step == 0) {
                            step = 1;
                        }

                        if (step == 1) {
                            coord1Label.setText(String.format("坐标: (X:%d, Y:%d)", mousePos.x, mousePos.y));
                            step2Label.setVisible(true);
                            coord2Label.setVisible(true);
                            step = 2;
                            point1 = mousePos; // 保存第一步坐标
                        } else if (step == 2) {
                            coord2Label.setText(String.format("坐标: (X:%d, Y:%d)", mousePos.x, mousePos.y));
                            point2 = mousePos; // 保存第二步坐标
                        }
                    });
                }
            }
        };

        // 注册监听器
        try {
            GlobalScreen.addNativeKeyListener(configListener);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 显示对话框
        configStage.show();

        // 对话框关闭时移除监听器
        configStage.setOnHidden(e -> {
            GlobalScreen.removeNativeKeyListener(configListener);
            step = 0;
        });
    }

    private void showMessageDialog(String title, String message) {
        Stage dialog = new Stage();
        dialog.initModality(Modality.APPLICATION_MODAL);
        dialog.initOwner(primaryStage);
        dialog.setTitle(title);

        Label messageLabel = new Label(message);
        Button okButton = new Button("确定");
        okButton.setOnAction(e -> dialog.close());

        VBox dialogLayout = new VBox(20);
        dialogLayout.setPadding(new Insets(20));
        dialogLayout.setAlignment(Pos.CENTER);
        dialogLayout.getChildren().addAll(messageLabel, okButton);

        Scene dialogScene = new Scene(dialogLayout, 300, 150);
        dialog.setScene(dialogScene);
        dialog.show();
    }

    @Override
    public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {
    }

    @Override
    public void nativeKeyPressed(NativeKeyEvent e) {
        if (step > 0 || !startStatus) {
            return;
        }

        if (e.getKeyCode() == NativeKeyEvent.VC_Q) {
            System.out.println("按了Q...");
            if (skillConfigData == null) {
                System.out.println("未读取到配置");
                return;
            }

            List<CustomPoint> pointList = skillConfigData.getPoint();
            if (pointList == null || pointList.size() <=0){
                System.out.println("未读取到坐标配置，请重新配置");
                return;
            }
            List<SkillInfo> skills = skillConfigData.getSkills();
            if (skills == null || skills.size() <=0){
                System.out.println("未读取到技能配置，请重新配置");
                return;
            }

            for (SkillInfo skillInfo : skills) {
                boolean match = true;
                List<CustomColor> colors = skillInfo.getColor();

                for (int j = 0; j < colors.size(); j++) {
                    CustomPoint point = pointList.get(j);
                    Color currentColor = robot.getPixelColor(point.getX(), point.getY());

                    if (!colors.get(j).compare(currentColor)) {
                        System.out.println("不匹配");
                        match = false;
                        break;
                    }
                }

                if (match) {
                    String keyBinding = skillInfo.getKeyBinding();
                    switch (keyBinding) {
                        case "-":
                            robot.keyPress(KeyEvent.VK_MINUS);
                            robot.keyRelease(KeyEvent.VK_MINUS);
                            break;
                        case "=":
                            robot.keyPress(KeyEvent.VK_EQUALS);
                            robot.keyRelease(KeyEvent.VK_EQUALS);
                            break;
                        case "3":
                            robot.keyPress(KeyEvent.VK_3);
                            robot.keyRelease(KeyEvent.VK_3);
                            break;
                        case "4":
                            robot.keyPress(KeyEvent.VK_4);
                            robot.keyRelease(KeyEvent.VK_4);
                            break;
                        default:
                    }
                    break;
                }
            }
        }
    }

    private void saveConfigToFile() {
        // 检查是否完成所有配置步骤
        if (point1 == null || point2 == null) {
            showMessageDialog("配置错误", "请先完成所有配置步骤！");
            return;
        }

        // 创建配置对象
        SkillConfigData config = new SkillConfigData();

        // 添加坐标点
        List<CustomPoint> points = new ArrayList<>();
        points.add(new CustomPoint(point1.x, point1.y));
        points.add(new CustomPoint(point2.x, point2.y));
        config.setPoint(points);

        // 添加技能配置（示例数据）
        List<SkillInfo> skills = new ArrayList<>();
        // ... 添加技能配置 ...
        config.setSkills(skills);

        // 保存到文件
        String currentDir = System.getProperty("user.dir");
        String filePath = Paths.get(currentDir, "config.json").toString();

        // 使用Gson保存JSON
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        try (FileWriter writer = new FileWriter(filePath)) {
            gson.toJson(config, writer);
            System.out.println("配置已保存到: " + filePath);
        } catch (IOException ex) {
            ex.printStackTrace();
            showMessageDialog("保存错误", "保存配置失败: " + ex.getMessage());
        }
    }

    @Override
    public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) {
    }
}
